package core.cards.election.gui;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;

import core.cards.IFormBackend;
import core.cards.election.model.ElectionBackend;
import core.cards.election.model.VotingCard;
import core.cards.election.model.VotingCardOption;

public class CmpElectionWizardPage extends Composite {
	private static class ViewerLabelProvider extends LabelProvider {
		public Image getImage(Object element) {
			return super.getImage(element);
		}

		public String getText(Object element) {
			if (element instanceof VotingCard) {
				return ((VotingCard) element).getName();
			}
			if (element instanceof VotingCardOption) {
				return ((VotingCardOption) element).getName();
			}
			return null;
		}
	}

	private static class TreeContentProvider implements ITreeContentProvider {
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}

		public void dispose() {
		}

		public Object[] getElements(Object inputElement) {
			return getChildren(inputElement);
		}

		public Object[] getChildren(Object parentElement) {
			if (parentElement instanceof ElectionBackend) {
				return ((ElectionBackend) parentElement).getVotingCardList().toArray();
			}
			if (parentElement instanceof VotingCard) {
				return ((VotingCard) parentElement).getVotingCardOptionList().toArray();
			}
			return null;
		}

		public Object getParent(Object element) {
			if (element instanceof ElectionBackend) {
				return null;
			}
			if (element instanceof VotingCard) {
				return ((VotingCard) element).getElectionFormBackend();
			}
			if (element instanceof VotingCardOption) {
				return ((VotingCardOption) element).getVotingCard();
			}
			return null;
		}

		public boolean hasChildren(Object element) {
			return (getChildren(element) != null && getChildren(element).length > 0);
		}
	}
	
	private ElectionBackend electionBackend;

	private TreeViewer trVwrElectionCards;
	private Tree trElectionCards;

	private Button btnPreview;
	private Button btnAddVotingCard;
	private Button btnEdit;
	private Button btnDelete;

	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 */
	public CmpElectionWizardPage(Composite parent, int style) {
		super(parent, style);
		
		electionBackend = new ElectionBackend();

		setLayout(new GridLayout(2, false));

		trVwrElectionCards = new TreeViewer(this, SWT.BORDER);
		trElectionCards = trVwrElectionCards.getTree();
		trElectionCards.setLinesVisible(true);
		trElectionCards.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				if (event.getSource() instanceof VotingCard) {
					// FIXME możemy obsłużyć
				}
			}
		});
		trElectionCards.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		trVwrElectionCards.setLabelProvider(new ViewerLabelProvider());
		trVwrElectionCards.setContentProvider(new TreeContentProvider());
		trVwrElectionCards.setInput(electionBackend);

		Composite cmpButtons = new Composite(this, SWT.NONE);
		cmpButtons.setLayout(new FillLayout(SWT.VERTICAL));
		GridData gd_cmpButtons = new GridData(SWT.CENTER, SWT.TOP, false, false, 1, 1);
		gd_cmpButtons.widthHint = 185;
		cmpButtons.setLayoutData(gd_cmpButtons);

		btnPreview = new Button(cmpButtons, SWT.NONE);
		btnPreview.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				DlgElectionPreview dlgElectionPreview = new DlgElectionPreview(getShell(), electionBackend);
				dlgElectionPreview.open();
			}
		});
		btnPreview.setText("Preview");

		new Label(cmpButtons, SWT.SEPARATOR | SWT.HORIZONTAL);

		btnAddVotingCard = new Button(cmpButtons, SWT.NONE);
		btnAddVotingCard.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				VotingCard newVotingCard = new VotingCard(electionBackend);
				WzdAddEditVotingCard wzdAddEditVotingCard = new WzdAddEditVotingCard(true, newVotingCard);

				WizardDialog wzdDlg = new WizardDialog(getShell(), wzdAddEditVotingCard);
				wzdDlg.open();

				if (wzdDlg.getReturnCode() == IDialogConstants.OK_ID) {
					electionBackend.addVotingCard(newVotingCard);
					refreshPage();
				}
			}
		});
		btnAddVotingCard.setText("Add Voting Card");

		Button btnAddVotingCardOption = new Button(cmpButtons, SWT.NONE);
		btnAddVotingCardOption.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				IStructuredSelection selection = (IStructuredSelection) trVwrElectionCards.getSelection();
				Object selectedObject = selection.getFirstElement();
				if (selectedObject != null) {
					if (selectedObject instanceof VotingCard) {
						VotingCard selectedVotingCard = (VotingCard) selectedObject;
						VotingCardOption newVotingCardOption = new VotingCardOption(selectedVotingCard);

						WzdAddEditVotingCardOption wzdAddEditVotingCardOption = new WzdAddEditVotingCardOption(true, newVotingCardOption);
						WizardDialog wzdDlg = new WizardDialog(getShell(), wzdAddEditVotingCardOption);
						wzdDlg.open();

						if (wzdDlg.getReturnCode() == IDialogConstants.OK_ID) {
							selectedVotingCard.addVotingCardOption(newVotingCardOption);
							refreshPage();
						}
					}
				}
				refreshPage();
			}
		});
		btnAddVotingCardOption.setText("Add Voting Card Option");

		btnEdit = new Button(cmpButtons, SWT.NONE);
		btnEdit.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				IStructuredSelection selection = (IStructuredSelection) trVwrElectionCards.getSelection();
				Object selectedObject = selection.getFirstElement();
				if (selectedObject != null) {
					if (selectedObject instanceof VotingCard) {
						WzdAddEditVotingCard wzdAddEditVotingCard = new WzdAddEditVotingCard(false, (VotingCard) selectedObject);
						WizardDialog wzdDlg = new WizardDialog(getShell(), wzdAddEditVotingCard);
						wzdDlg.open();
					} else if (selectedObject instanceof VotingCardOption) {
						WzdAddEditVotingCardOption wzdAddEditVotingCardOption = new WzdAddEditVotingCardOption(false, (VotingCardOption) selectedObject);
						WizardDialog wzdDlg = new WizardDialog(getShell(), wzdAddEditVotingCardOption);
						wzdDlg.open();
					}
					refreshPage();
				}
			}
		});
		btnEdit.setText("Edit");

		new Label(cmpButtons, SWT.SEPARATOR | SWT.HORIZONTAL);

		btnDelete = new Button(cmpButtons, SWT.NONE);
		btnDelete.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				IStructuredSelection selection = (IStructuredSelection) trVwrElectionCards.getSelection();
				Object selectedObject = selection.getFirstElement();
				if (selectedObject != null) {
					if (selectedObject instanceof VotingCard) {
						electionBackend.removeVotingCard((VotingCard) selectedObject);
					} else if (selectedObject instanceof VotingCardOption) {
						VotingCardOption selectedVotingCardOption = (VotingCardOption) selectedObject;
						VotingCard votingCardOptionParent = selectedVotingCardOption.getVotingCard();
						votingCardOptionParent.removeVotingCardOption(selectedVotingCardOption);
					}
					refreshPage();
				}
			}
		});
		btnDelete.setText("Delete");
	}

	private void refreshPage() {
		trVwrElectionCards.setInput(electionBackend);
		trVwrElectionCards.expandAll();
	}

	public void setFormBackend(ElectionBackend formBackend) {
		this.electionBackend = formBackend;
		refreshPage();
	}

	public IFormBackend getFormBackend() {
		return electionBackend;
	}

	@Override
	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}
}
